const { eval_code } = require("./share_data");
const { BaseCommand } = require("./base");

class TraversalCommand extends BaseCommand {
    async execute() {
        const data = this.selfData;
        return traversal(
            this.content,
            eval_code(data.handler),
            eval_code(data.sizeOf),
            eval_code(data.childAt),
            data.output,
            eval_code(data.filter),
        );
    }

    getRequireContent() {
        return true;
    }

    getRequiredParams() {
        return ["sizeOf", "childAt", "handler"];
    }
}

module.exports = {
    TraversalCommand,
};

function traversal(root, handler, sizeOf, childAt, output, filter) {
    if (!filter || filter(root)) {
        handler(root, output);
    }
    for (let i = 0, size = sizeOf(root) || 0; i < size; ++i) {
        const child = childAt(root, i);
        traversal(child, handler, sizeOf, childAt, output, filter);
    }
    return output;
}
